import libtcodpy as libtcod
from object import Object
from tile import Tile

MIN_ROOM_SIZE = 5
MAX_ROOM_SIZE = 10
ROOM_MONSTER_CHANCE = 0.3

class Room:
    def __init__(self, x, y, width, height):
        self.x1 = x - 1
        self.y1 = y - 1
        self.x2 = x + width
        self.y2 = y + height

    def centerX(self):
        return( abs(self.x1 + self.x2) / 2 )

    def centerY(self):
        return( abs(self.y1 + self.y2) / 2 )

    def dist(self, room):
        dx = self.centerX() - room.centerX()
        dy = self.centerY() - room.centerY()
        return(dx * dx + dy * dy)

    def nearest(self, rooms):
        best = rooms[0]
        for room in rooms:
            if self.dist(room) < self.dist(best):
                best = room
        return best

    def intersects(self, room):
        return( self.x1 < room.x2 and 
                room.x1 < self.x2 and
                self.y1 < room.y2 and
                room.y1 < self.y2 )

    def carve(self, map):
        for x in range( self.x1 + 1, self.x2 ):
            for y in range( self.y1 + 1, self.y2 ):
                map[x][y].clear()

    def spawn_monsters(self, objects, map):
        if libtcod.random_get_int( 0, 0, 100 ) < ROOM_MONSTER_CHANCE * 100:
            x = libtcod.random_get_int( 0, self.x1 + 1, self.x2 - 1 )
            y = libtcod.random_get_int( 0, self.y1 + 1, self.y2 - 1 )
            if map[x][y].is_blocked():
                return
            name = "Rattata"
            symbol = 'r'
            color = libtcod.gray
            new_monster = Object( x, y, name, symbol, color, True, map )
            objects.append( new_monster )

def room_tunnel(map, room1, room2, list):
    # Shuffle
    if libtcod.random_get_int( 0, 0, 1 ) == 1:
        roomx = room1
        room1 = room2
        room2 = roomx

    # Find coordinates
    x1 = room1.centerX()
    y1 = room1.centerY()
    x2 = room2.centerX()
    y2 = room2.centerY()

    def tunnel(map, x1, y1, x2, y2, list):
        # Dig horizontally
        hor = Room( min(x1,x2), y2, abs(x1-x2)+1, 1 )
        hor.carve( map )
        list.append( hor )
    
        # Dig vertically
        ver = Room( x1, min(y1,y2), 1, abs(y1-y2)+1 )
        ver.carve( map )
        list.append( ver )

    tunnel(map, x1, y1, x2, y2, list)

    return map
        

def get_map(width, height, objects):
    map = [ [ Tile(True)
              for y in range(height) ]
            for x in range(width) ]

    rooms = []

    # Initial room
    room1 = Room( width/2 - 1, height/2 - 1, 3, 3 )
    room1.carve( map )

    # Generate rooms
    num_rooms = width * height / 180
    for roomNo in range(num_rooms):
        room_width = libtcod.random_get_int( 0, MIN_ROOM_SIZE, MAX_ROOM_SIZE )
        room_height = libtcod.random_get_int( 0, MIN_ROOM_SIZE, MAX_ROOM_SIZE )
        room_x = libtcod.random_get_int( 0, 1, width - room_width - 1 )
        room_y = libtcod.random_get_int( 0, 1, height - room_height - 1 )
        new_room = Room( room_x, room_y, room_width, room_height )
        
        new_room.spawn_monsters( objects, map )

        new_room.carve( map )
        rooms.append( new_room )

    group1 = [room1]

    while True:
        added = True
        while added:
            added = False
            for r in rooms:
                for g in group1:
                    if g.intersects(r):
                        rooms.remove(r)
                        group1.append(r)
                        break
        print(len(rooms))
        if len(rooms) > 0:
            room_tunnel( map, rooms[0], rooms[0].nearest(group1), group1 )
            group1.append(rooms[0])
            rooms.remove(rooms[0])
        else:
            break

    return map
